package com.haixiaoke.saas.repository.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.haixiaoke.saas.repository.exception.BizException;
import com.haixiaoke.saas.repository.mapper.ApartmentBillRuleMapper;
import com.haixiaoke.saas.repository.pojo.ApartmentBillRule;
import com.haixiaoke.saas.repository.pojo.ApartmentItemRuleRef;
import com.haixiaoke.saas.repository.pojo.ApartmentOrderChargeItem;
import com.haixiaoke.saas.repository.service.IApartmentBillRuleService;
import com.haixiaoke.saas.repository.service.IApartmentItemRuleRefService;
import com.haixiaoke.saas.repository.service.IApartmentOrderChargeItemService;
import com.haixiaoke.saas.repository.vo.ApartmentBillRuleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 账单生成规则Service业务层处理
 *
 * @author qixi
 * @date 2023-06-16
 */
@Service
public class ApartmentBillRuleServiceImpl implements IApartmentBillRuleService {
    @Autowired
    private ApartmentBillRuleMapper apartmentBillRuleMapper;
    @Autowired
    private IApartmentItemRuleRefService apartmentItemRuleRefService;
    @Autowired
    private IApartmentOrderChargeItemService apartmentOrderChargeItemService;

    /**
     * 查询账单生成规则
     *
     * @param ruleId 账单生成规则主键
     * @return 账单生成规则
     */
    @Override
    public ApartmentBillRule selectApartmentBillRuleByRuleId(Long ruleId) {
        return apartmentBillRuleMapper.selectApartmentBillRuleByRuleId(ruleId);
    }

    /**
     * 查询账单生成规则列表
     *
     * @param apartmentBillRule 账单生成规则
     * @return 账单生成规则
     */
    @Override
    public List<ApartmentBillRuleVo> selectApartmentBillRuleList(ApartmentBillRule apartmentBillRule) {
        List<ApartmentBillRuleVo> vos = apartmentBillRuleMapper.selectApartmentBillRuleList(apartmentBillRule);
        for (ApartmentBillRuleVo vo : vos) {
            Long ruleId = vo.getRuleId();
            List<ApartmentItemRuleRef> apartmentItemRuleRefs = apartmentItemRuleRefService.selectApartmentItemRuleRefByRuleId(ruleId);
            vo.setRefs(apartmentItemRuleRefs);
        }
        return vos;
    }

    /**
     * 新增账单生成规则
     *
     * @param apartmentBillRule 账单生成规则
     * @return 结果
     */
    @Override
    public int insertApartmentBillRule(ApartmentBillRule apartmentBillRule) {
        apartmentBillRule.setCreateTime(new Date());
        return apartmentBillRuleMapper.insertApartmentBillRule(apartmentBillRule);
    }

    /**
     * 修改账单生成规则
     *
     * @param apartmentBillRule 账单生成规则
     * @return 结果
     */
    @Override
    public int updateApartmentBillRule(ApartmentBillRule apartmentBillRule) {
        apartmentBillRule.setUpdateTime(new Date());
        return apartmentBillRuleMapper.updateApartmentBillRule(apartmentBillRule);
    }

    @Override
    @Transactional
    public int updateApartmentBillRuleAndRuleRef(ApartmentBillRule apartmentBillRule) {
        Long ruleId = apartmentBillRule.getRuleId();
        String orderId = apartmentBillRule.getOrderId();
        String userId = apartmentBillRule.getUserId();


        List<ApartmentItemRuleRef> refs = apartmentBillRule.getRefs();
        // bug 2348
        if (refs.size() == 0) {
            throw new BizException("请添加账单类型!");
        }

        //校验收费项目名称是否重复
        List<String> itemNames = refs.stream().filter(m->ObjectUtil.isNull(m.getItemId()))
                .map(ApartmentItemRuleRef::getItemName).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(itemNames) && !apartmentItemRuleRefService.checkItemNamesUnique(itemNames,ruleId)){
            throw new BizException("收费项目名称已存在!");
        }

        //校验收费项目名称是否重复
        List<Double> isNegative = refs.stream().map(ApartmentItemRuleRef::getUnitPrice)
                .filter(unitPrice ->(unitPrice < 0)).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(isNegative)){
            throw new BizException("单价不能为负数");
        }

        //删除收费项目关联关系
        List<Long> refIds = refs.stream().map(ApartmentItemRuleRef::getRefId).
                filter(ObjectUtil::isNotNull).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(refIds)){
            apartmentItemRuleRefService.deleteApartmentItemRuleRefNotInRefIds(ruleId,refIds);
        }


        for (ApartmentItemRuleRef ref : refs) {

            Double unitPrice = ref.getUnitPrice();
            if (ObjectUtil.isNull(unitPrice)){
                throw new BizException("单价不能为空!");
            }
            Long itemId = ref.getItemId();
            if (ObjectUtil.isNotNull(itemId)){
                apartmentItemRuleRefService.updateApartmentItemRuleRef(ref);
            }else {
                ApartmentOrderChargeItem item = new ApartmentOrderChargeItem();
                item.setItemName(ref.getItemName());
                item.setItemUnit(ref.getItemUnit());
                item.setOrderId(orderId);
                item.setCreateBy(userId);
                item.setCreateTime(new Date());
                apartmentOrderChargeItemService.insertApartmentOrderChargeItem(item);
                ref.setItemId(item.getItemId());
                ref.setRuleId(ruleId);
                ref.setItemType(ApartmentItemRuleRef.ITEM_TYPE_ORDER_ITEM);
                apartmentItemRuleRefService.insertApartmentItemRuleRef(ref);
            }
        }

        apartmentBillRule.setUpdateTime(new Date());
        return apartmentBillRuleMapper.updateApartmentBillRule(apartmentBillRule);
    }

    /**
     * 批量删除账单生成规则
     *
     * @param ruleIds 需要删除的账单生成规则主键
     * @return 结果
     */
    @Override
    public int deleteApartmentBillRuleByRuleIds(Long[] ruleIds) {
        return apartmentBillRuleMapper.deleteApartmentBillRuleByRuleIds(ruleIds);
    }

    /**
     * 删除账单生成规则信息
     *
     * @param ruleId 账单生成规则主键
     * @return 结果
     */
    @Override
    public int deleteApartmentBillRuleByRuleId(Long ruleId) {
        return apartmentBillRuleMapper.deleteApartmentBillRuleByRuleId(ruleId);
    }

    @Override
    public List<ApartmentBillRule> selectApartmentBillRuleByPeriod() {
       return apartmentBillRuleMapper.selectApartmentBillRuleByPeriod();
    }

    @Override
    public ApartmentBillRule selectApartmentBillRuleByOrderId(String orderId) {
        return apartmentBillRuleMapper.selectApartmentBillRuleByOrderId(orderId);
    }

    @Override
    public int deleteApartmentBillRuleByOrderId(String orderId) {
        return apartmentBillRuleMapper.deleteApartmentBillRuleByOrderId(orderId);
    }
}
